package br.com.unifebe.tcc.applets;


import java.util.HashMap;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.OwnerPIN;
import javacard.framework.Util;

public class AppletCliente extends Applet {

	final static byte CLA_APPLET_CLIENTE = (byte) 0xB0;

	final static byte INS_SET_ID = (byte) 0x10;
	final static byte INS_GET_ID = (byte) 0x20;
	final static byte INS_SET_NOME = (byte) 0x30;
	final static byte INS_GET_NOME = (byte) 0x40;
	final static byte INS_SET_SALDO  = (byte) 0x50;
	final static byte INS_GET_SALDO  = (byte) 0x60;
	final static byte INS_SET_QTD_VENDA = (byte) 0x70;
	final static byte INS_GET_QTD_VENDA = (byte) 0x80; 

	OwnerPIN pin;
	// maximum number of incorrect tries before the
	// PIN is blocked
	final static byte PIN_TRY_LIMIT =(byte)0x03;
	// maximum size PIN
	final static byte MAX_PIN_SIZE =(byte)0x08;

	private HashMap<String, Object> map = null; 

	private AppletCliente( byte[] bArray, short bOffset, byte bLength ) {

		pin = new OwnerPIN(PIN_TRY_LIMIT,   MAX_PIN_SIZE);

		this.map = new HashMap<String, Object>();

		register(bArray, (short) (bOffset + 1), bArray[bOffset]);

	}		
	public static void install(byte[] bArray, short bOffset, byte bLength) {

		new AppletCliente(bArray, bOffset, bLength);
	}

	@Override
	public void process(APDU apdu) {

		if (selectingApplet()) {
			return;
		}

		byte[] buf = apdu.getBuffer();
		switch (buf[ISO7816.OFFSET_INS]) {
		case INS_SET_ID:
			//			pessoa.setNome(receberDados(apdu));	
			map.put("id", receberDados(apdu));
			break;
		case INS_GET_ID:
			//			enviarDados(apdu, pessoa.getNome());
			enviarDados(apdu, (byte[]) map.get("id"));
			break;

		case INS_SET_NOME:
			//			pessoa.setIdade(receberDados(apdu));
			map.put("nome", receberDados(apdu));
			break;

		case INS_GET_NOME:
			//			enviarDados(apdu, pessoa.getIdade());
			enviarDados(apdu, (byte[]) map.get("nome"));
			break;

		case INS_SET_SALDO:
			//			pessoa.setTelefone(receberDados(apdu));
			map.put("saldo", receberDados(apdu));
			break;

		case INS_GET_SALDO:
			//			enviarDados(apdu, pessoa.getTelefone());
			enviarDados(apdu, (byte[]) map.get("saldo"));
			break;

		case INS_SET_QTD_VENDA:
			//			pessoa.setObservacao(receberDados(apdu));
			map.put("venda", receberDados(apdu));
			break;

		case INS_GET_QTD_VENDA:
			//			enviarDados(apdu, pessoa.getObservacao());
			enviarDados(apdu, (byte[]) map.get("venda"));
			break;
		default:

			ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
		}
	}

	private byte[] receberDados(APDU apdu) {		
		byte[] dados = new byte[127]; 
		byte[] buffer = apdu.getBuffer();		
		short lengthDados = (short) (buffer[ISO7816.OFFSET_CDATA] & 0x00FF);

		if (lengthDados == 0)
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

		Util.arrayCopy(buffer, (short)((ISO7816.OFFSET_CDATA) & 0x00FF),
				dados, (short) 0, (short) 100);

		return dados; 
	}

	private void enviarDados(APDU apdu, byte[] dados) {

		short lengthDados = (short) dados.length;

		if (lengthDados == 0) 
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

		apdu.setOutgoing();
		apdu.setOutgoingLength(lengthDados);
		apdu.sendBytesLong(dados, (short) 0 , lengthDados);

	}

}
